<?php

namespace app\common\controller;

class PreciseCalculator
{
    const EXTRA_PRECISION = 2;

    /**
     * Notes:  相加
     * User: AerYYY
     * Date: 7/9/25
     * @param $a
     * @param $b
     * @param $scale
     * @return string
     */
    public static function add($a, $b, $scale = 2)
    {
        $result = bcadd($a, $b, $scale + self::EXTRA_PRECISION);
        return self::round($result, $scale);
    }

    /**
     * Notes: 相减
     * User: AerYYY
     * Date: 7/9/25
     * @param $a
     * @param $b
     * @param $scale
     * @return string
     */
    public static function sub($a, $b, $scale = 2)
    {
        $result = bcsub($a, $b, $scale + self::EXTRA_PRECISION);
        return self::round($result, $scale);
    }

    /**
     * Notes: 相乘
     * User: AerYYY
     * Date: 7/9/25
     * @param $a
     * @param $b
     * @param $scale
     * @return string
     */
    public static function mul($a, $b, $scale = 2)
    {
        $result = bcmul($a, $b, $scale + self::EXTRA_PRECISION);
        return self::round($result, $scale);
    }

    /**
     * Notes: 相除
     * User: AerYYY
     * Date: 7/9/25
     * @param $a
     * @param $b
     * @param $scale
     * @return string
     */
    public static function div($a, $b, $scale = 2)
    {
        if (bccomp($b, '0', $scale) === 0) {
            exception('Division by zero');
        }
        $result = bcdiv($a, $b, $scale + self::EXTRA_PRECISION);
        return self::round($result, $scale);
    }


    /**
     * Notes: 银行家算法
     * User: AerYYY
     * Date: 7/9/25
     * @param $number
     * @param $precision
     * @return string
     */
    private static function round($number, $precision)
    {
        $factor = pow(10, $precision);
        $rounded = round((float)$number * $factor, 0, PHP_ROUND_HALF_EVEN);
        return bcdiv($rounded, $factor, $precision);
    }
}